package com.hzit.hzb.core.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzit.common.exception.Assert;
import com.hzit.common.result.ResponseEnum;
import com.hzit.hzb.core.enums.BorrowerStatusEnum;
import com.hzit.hzb.core.enums.IntegralEnum;
import com.hzit.hzb.core.pojo.dto.ExcelDictDTO;
import com.hzit.hzb.core.pojo.entity.*;
import com.hzit.hzb.core.mapper.BorrowerMapper;
import com.hzit.hzb.core.pojo.vo.BorrowerApprovalVO;
import com.hzit.hzb.core.pojo.vo.BorrowerAttachVO;
import com.hzit.hzb.core.pojo.vo.BorrowerDetailVO;
import com.hzit.hzb.core.pojo.vo.BorrowerVO;
import com.hzit.hzb.core.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 借款人 服务实现类
 * </p>
 *
 * @author hbxfwf
 * @since 2024-08-27
 */
@Service
public class BorrowerServiceImpl extends ServiceImpl<BorrowerMapper, Borrower> implements BorrowerService {

	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private BorrowerAttachService attachService;
	@Autowired
	private DictService dictService;
	@Autowired
	private UserIntegralService userIntegralService;
	@Autowired
	private IntegralGradeService integralGradeService;

	/**
	 * 保存借款人信息
	 * @param vo
	 * @param userId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)       // 针对所有异常都会回滚
	public void saveBorrowerVOByUserId(BorrowerVO vo, Long userId) {
		// 1.1 根据userId查询出用户信息
		UserInfo userInfo = userInfoService.getById(userId);
		// 1.2 构造借款人对象信息
		Borrower borrower = new Borrower();
		// 1.3 复制前端传入（上传）的借款人信息
		BeanUtil.copyProperties(vo,borrower);
		borrower.setName(userInfo.getName());
		borrower.setIdCard(userInfo.getIdCard());
		borrower.setMobile(userInfo.getMobile());
		borrower.setUserId(userId);
		borrower.setStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());        // 设置借款人状态为认证中
		// 1.4 添加借款人信息到db中
		this.save(borrower);
		// 1.5 修改用户借款状态
		userInfo.setBorrowAuthStatus(BorrowerStatusEnum.AUTH_RUN.getStatus());    // 设置用户的借款状态
		userInfoService.updateById(userInfo);

		// 1.6 添加借款人附件信息
		List<BorrowerAttach> borrowerAttachList = vo.getBorrowerAttachList();
		borrowerAttachList.forEach(attach -> {
			attach.setBorrowerId(borrower.getId());     // 设置借款人id
		});
		// 1.7 保存借款人附件信息
		attachService.saveBatch(borrowerAttachList);
	}

	/**
	 * 根据用户id获取借款人的状态信息
	 * @param userId
	 * @return
	 */
	@Override
	public Integer getBorrowerStatus(Long userId) {
		// 1. 根据用户id查询借款人
		Borrower borrower = this.getOne(new QueryWrapper<Borrower>().eq("user_id", userId));
		if (borrower == null) {
			return BorrowerStatusEnum.NO_AUTH.getStatus();
		}
		// 2. 返回借款人状态
		return borrower.getStatus();
	}

	/**
	 * 分页带条件查询
	 * @param page 当前页
	 * @param limit 每页大小
	 * @param keywords 查询关键字
	 * @return
	 */
	@Override
	public IPage<Borrower> getPageList(Long page, Long limit, String keywords) {
		// 1.1 构造一个查询的分页对象
		IPage page1 = new Page<>(page, limit);
		// 1.2 开始分页查询
		return this.page(page1, new QueryWrapper<Borrower>()
				.like("name", keywords)
				.or().like("id_card", keywords)
				.or().like("mobile", keywords)
				.orderByDesc("id")
		);
	}

	/**
	 * 根据借款人id查询借款人详细信息
	 * @param id
	 * @return
	 */
	@Override
	public BorrowerDetailVO getDetailsById(Long id) {
		// 1. 根据借款人id查询借款对象
		Borrower borrower = this.getById(id);
		// 2. 构造借款人详细信息对象
		BorrowerDetailVO vo = new BorrowerDetailVO();
		// 3. 复制借款人信息到借款人详细信息对象
		BeanUtil.copyProperties(borrower,vo);
		vo.setMarry(borrower.getMarry() ? "己婚" : "未婚");
		vo.setSex(borrower.getSex() == 1 ? "男" : "女");
		// 4. 查询出学历名称
		String education = getDictNameByDictCodeAndValue("education",vo.getEducation());
		vo.setEducation(education);
		// 5. 查询出行业名称
		String industry = getDictNameByDictCodeAndValue("industry",vo.getIndustry());
		vo.setIndustry(industry);
		// 6. 查询收入
		String income = getDictNameByDictCodeAndValue("income",vo.getIncome());
		vo.setIncome(income);
		// 7. 查询收入来源
		String returnSource = getDictNameByDictCodeAndValue("returnSource",vo.getReturnSource());
		vo.setReturnSource(returnSource);
		// 8. 查询关系
		String relation = getDictNameByDictCodeAndValue("relation",vo.getContactsRelation());
		vo.setContactsRelation(relation);
		// 9. 设置审核状态信息
		vo.setStatus(BorrowerStatusEnum.getMsgByStatus(borrower.getStatus()));
		// 10. 设置借款人的附件信息
		List<BorrowerAttach> borrowerAttaches = attachService.list(new QueryWrapper<BorrowerAttach>().eq("borrower_id", id));
		// 11. 处理借款人附件信息为List<BorrowerAttachVO>
		List<BorrowerAttachVO> collect = borrowerAttaches.stream().map(attach -> {
			BorrowerAttachVO attachVO = new BorrowerAttachVO();
			attachVO.setImageType(attach.getImageType());
			attachVO.setImageUrl(attach.getImageUrl());
			return attachVO;
		}).collect(Collectors.toList());
		// 12. 设置给vo对象
		vo.setBorrowerAttachVOList(collect);
		// 13. 最后返回
		return vo;
	}

	/**
	 * 借款人借款额度审批
	 * 思路：
	 *  1、修改借款人的状态信息
	 *  2、向user_integral表中添加借款详细的积分（车辆、房产、身份证等）
	 *  3、向user_info表添加总积分，修改审批状态
	 */
	@Override
	public void approval(BorrowerApprovalVO vo) {
		// 1. 根据借款人id获取借款人信息
		Long borrowerId = vo.getBorrowerId();
		Borrower borrower = this.getById(borrowerId);
		borrower.setStatus(vo.getStatus());         // 修改借款人状态
		this.updateById(borrower);

		// 2. 获取用户信息
		Long userId = borrower.getUserId();
		UserInfo userInfo = userInfoService.getById(userId);

		// 3. 添加基础分数到user_integral表中
		UserIntegral userIntegral = new UserIntegral();
		userIntegral.setUserId(userId);
		userIntegral.setContent("借款人基本信息");
		userIntegral.setIntegral(vo.getInfoIntegral());
		userIntegralService.save(userIntegral);

		// 4. 定义总积分
		Integer totalIntegral = userInfo.getIntegral() + vo.getInfoIntegral();

		// 5. 添加身份证信息对应的积分到user_integral表中
		if(vo.getIsIdCardOk()){
			// 5.1 累加积分
			totalIntegral += IntegralEnum.BORROWER_IDCARD.getIntegral();
			// 5.2 构造UserIntegral对象
			UserIntegral idCartIntegral = new UserIntegral();
			idCartIntegral.setIntegral(IntegralEnum.BORROWER_IDCARD.getIntegral());
			idCartIntegral.setUserId(userId);
			idCartIntegral.setContent(IntegralEnum.BORROWER_IDCARD.getMsg());
			userIntegralService.save(idCartIntegral);
		}

		// 6. 添加车辆对应的积分到user_integral表中
		if(vo.getIsCarOk()){
			// 6.1 累加积分
			totalIntegral += IntegralEnum.BORROWER_CAR.getIntegral();
			// 6.2 构造要添加的积分详细对象
			UserIntegral carIntegral = new UserIntegral();
			carIntegral.setIntegral(IntegralEnum.BORROWER_CAR.getIntegral());
			carIntegral.setContent(IntegralEnum.BORROWER_CAR.getMsg());
			carIntegral.setUserId(userId);
			userIntegralService.save(carIntegral);
		}

		// 7. 添加房产对应的积分到user_integral表中
		if(vo.getIsHouseOk()){
			// 7.1 累加积分
			totalIntegral += IntegralEnum.BORROWER_HOUSE.getIntegral();
			// 7.2 构造要添加的积分详细对象
			UserIntegral houseIntegral = new UserIntegral();
			houseIntegral.setUserId(userId);
			houseIntegral.setContent(IntegralEnum.BORROWER_HOUSE.getMsg());
			houseIntegral.setIntegral(IntegralEnum.BORROWER_HOUSE.getIntegral());
			userIntegralService.save(houseIntegral);
		}

		// 8. 修改userInfo中的总积分
		userInfo.setIntegral(totalIntegral);
		// 9. 修改userInfo中的对借款额度的审核状态
		userInfo.setBorrowAuthStatus(vo.getStatus());
		// 10. 修改userInfo表
		userInfoService.updateById(userInfo);
	}

	/**
	 * 获取当前用户的借款额度
	 * @param userId
	 * @return
	 */
	@Override
	public BigDecimal getBorrowAmount(Long userId) {
		// 1. 根据userId获取UserInfo对象
		UserInfo userInfo = userInfoService.getById(userId);
		// 2. 判断是否存在，不存在抛出异常
		Assert.notNull(userInfo, ResponseEnum.LOGIN_MOBILE_ERROR);
		// 3. 得到借款用户的借款总积分值
		Integer integral = userInfo.getIntegral();
		// 4. 在积分等级表(integralGrade)根据积分的范围查询出借款额度
		IntegralGrade integralGrade = integralGradeService.getOne(new QueryWrapper<IntegralGrade>()
				.ge("integral_end", integral)
				.le("integral_start", integral)
		);
		if(integralGrade == null){
			return new BigDecimal("0");
		}
		// 5. 查询出借款额度并返回
		return integralGrade.getBorrowAmount();
	}

	/**
	 * 根据字典的dict_code加上value值得到字典的name
	 * @param dictCode
	 * @param value
	 * @return
	 */
	public String getDictNameByDictCodeAndValue(String dictCode, String value) {
		// 1. 根据dictCode查询出父字典对象
		Dict parentDict = dictService.getOne(new QueryWrapper<Dict>().eq("dict_code", dictCode));
		if(parentDict == null){
			return "";
		}
		// 2. 如果存在父字典
		Dict dict = dictService.getOne(new QueryWrapper<Dict>()
				.eq("parent_id", parentDict.getId())
				.eq("value", value)
		);
		if(dict == null){
			return "";
		}
		return dict.getName();
	}
}
